package com.lhfeiyu.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.lhfeiyu.dao.BonusDetailMapper;
import com.lhfeiyu.dao.BonusMapper;
import com.lhfeiyu.dao.base.BaseChatMapper;
import com.lhfeiyu.dao.base.BaseUserMapper;
import com.lhfeiyu.domain.base.Trade;
import com.lhfeiyu.po.Bonus;
import com.lhfeiyu.po.BonusDetail;
import com.lhfeiyu.po.base.BaseChat;
import com.lhfeiyu.po.base.BaseUser;
import com.lhfeiyu.service.base.BaseCommonFundService;
import com.lhfeiyu.service.base.CommonService;
import com.lhfeiyu.tools.base.Check;
import com.lhfeiyu.tools.base.DateFormat;
import com.lhfeiyu.tools.base.Result;
import com.lhfeiyu.tools.base.WxMessageFactory;

@Service
public class BonusService extends CommonService<Bonus>{
	@Autowired
	BonusMapper bonusMappper;
	@Autowired
	BonusDetailMapper bdMappper;
	@Autowired
	BaseChatMapper chatMapper;
	@Autowired
	BaseUserMapper userMapper;
	@Autowired
	BaseCommonFundService cfService;

	public String selectSumByCondition(Map<String,Object> map){
		return bonusMappper.selectSumByCondition(map);
	}
	
	public JSONObject addBonus(String payPass, BaseUser user, Bonus bonus, Double eachMoney, Date date, JSONObject json){
		Integer userId = user.getId();
		String username = user.getUsername();
		String userPhone = user.getPhone();
		
		bonus.setUserId(userId);
		bonus.setName(username);
		bonus.setCreateTime(date);
		bonus.setCreatedBy(username);//dict 143:红包交易
		//String linkUrl = "/bonusReceived";//TODO 资金变动通知
		//TODO 修改
		Trade trade = new Trade();
		trade.setUserId(userId);
		trade.setPhone(userPhone);
		trade.setUsername(username);
		trade.setMoney(bonus.getTotalMoney());
		//trade.setFundOptLevelCode(fundOptLevelCode);
		trade.setPayPass(payPass);
		trade.setInOrOut(2);
		trade.setPayTime(date);
		trade.setTradeUserId(userId);
		trade.setTradeUsername(username);
		trade.setTradeUserPhone(userPhone);
		trade.setTradeStatusCode("trade_status_done");
		trade.setCreatedBy(username);
		cfService.freezeMoney(json, trade, username);
		if(Result.hasError(json))return json;//如果出现错误，直接返回错误信息
		bonusMappper.insertSelective(bonus);
		int bonusId = bonus.getId();
		int typeId = bonus.getTypeId();
		int count = bonus.getCount();
		double totalMoney = bonus.getTotalMoney().doubleValue();
		List<BonusDetail> bdList = new ArrayList<BonusDetail>();
		double[] allocationMoney = new double[count]; 
		if(typeId == 1){//拼手气红包
			allocationMoney = getRandomBonus(count, allocationMoney, totalMoney);
		}else{//普通红包
			if(null == eachMoney){ 
				return Result.failure(json, "单个红包金额不正确", "bonusMoney_error"); 
			}
			for( int i = 0; i<count; i++ ){
				 allocationMoney[i] = eachMoney;   
	        }
		}
        for( int i = 0; i<count; i++ ){
        	BonusDetail bd = new BonusDetail();
        	double money = allocationMoney[i];
        	bd.setBonusId(bonusId);
        	bd.setMoney(new BigDecimal(money));
        	bd.setMainStatus(1);//还没有人接收
        	bd.setTypeId(bonus.getTypeId());//专场红包或个人红包(1,2)
        	bd.setLinkId(bonus.getLinkId());//关联的专场ID或用户ID
        	bd.setCreateTime(date);
        	bd.setCreatedBy(username);
        	bd.setCreatedAt(date);
        	bdList.add(bd);
        }
		bdMappper.insertBatch(bdList);
		return json;
	}
	
	private double[] getRandomBonus(int count, double[] allocationMoney, double totalMoney ){
		for( int i = count; i > 1; i-- ){
            //double surplusMoney = totalMoney - ( i - 1 ) * 0.01;  
            double surplusMoney = ( totalMoney - ( i - 1 ) * 0.01 ) / ( i / 2 );  //安全线  
            //设surplusMoney为15，1、获取[0,1500)随机数，2、获取  [1,1500]随机数，3、获取[0.01,15.00]随机数  
            double randomlyAssignedMoney = ( (int)( Math.random() * surplusMoney * 100 ) + 1 ) * 0.01;  
            //截取小数点后两位输出  
            BigDecimal aBigDecimal = new BigDecimal( randomlyAssignedMoney );  
            double moneyOfOnePerson = aBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
            //System.out.println( moneyOfOnePerson );  
            totalMoney -= randomlyAssignedMoney;  
            allocationMoney[i-1] = randomlyAssignedMoney;   
		}
		BigDecimal bg = new BigDecimal( totalMoney );  
        double remainingMoney = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
        //System.out.println( remainingMoney );  
        allocationMoney[0] = remainingMoney;  
		return allocationMoney;
	}
	
	public JSONObject receiveBonus(Integer bossId, BaseUser user, JSONObject json, Integer id){
		Integer userId = user.getId();
		String username = user.getUsername();
		String userPhone = user.getPhone();
		Date date = new Date();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("typeId", 2);
		map.put("senderId", bossId);
		map.put("receiverId", userId);
		map.put("notDeal", 1);
		List<BaseChat> chatList = chatMapper.selectListByCondition(map);
		if( Check.isNull(chatList) ){ 
			if(null != id){//如果不能向下执行，就将红包聊天消息改为已读
				BaseChat newChat = new BaseChat();
				newChat.setId(id);
				newChat.setReadTime(date);//已阅读
				newChat.setMainStatus(2);//已处理
				chatMapper.updateByPrimaryKeySelective(newChat);
			}
			return Result.failure(json, "您已经领取了红包，不能重复领取", "bonus_null"); 
		}
		map.clear();
		map.put("userId", bossId);
		map.put("notDeal", 1);
		List<Bonus> bonusList = bonusMappper.selectListByCondition(map);
		if( Check.isNull(bonusList) ){ 
			if(null != id){//如果不能向下执行，就将红包聊天消息改为已读
				BaseChat newChat = new BaseChat();
				newChat.setId(id);
				newChat.setReadTime(date);//已阅读
				newChat.setMainStatus(2);//已处理
				chatMapper.updateByPrimaryKeySelective(newChat);
			}
			return Result.failure(json, "红包已经被抢光了", "bonusList_null"); 
		}
		boolean success = false;
		for(Bonus b : bonusList){
			Integer bonusId = b.getId();
			map.clear();
			map.put("bonusId", bonusId);
			map.put("notDeal", 1);
			map.put("start", 0);
			map.put("count", 1);
			BonusDetail bd = bdMappper.selectByCondition(map);
			if(null != bd){
				BigDecimal tradeMoney = bd.getMoney();
				if(null == tradeMoney || tradeMoney.doubleValue() <= 0){
					if(null != id){//如果不能向下执行，就将红包聊天消息改为已读
						BaseChat newChat = new BaseChat();
						newChat.setId(id);
						newChat.setReadTime(date);//已阅读
						newChat.setMainStatus(2);//已处理
						chatMapper.updateByPrimaryKeySelective(newChat);
					}
					return Result.failure(json, "红包金额不正确", "bonusMoney_error"); 
				}
				//处理资金变更
				//String linkUrl = "/bonusReceived";
				//TODO 修改
				String moneyStr = String.valueOf(bd.getMoney());
				BaseUser bossUser = userMapper.selectByPrimaryKey(bossId);
				Trade trade = new Trade();
				trade.setUserId(bossUser.getId());
				trade.setPhone(bossUser.getPhone());
				trade.setUsername(bossUser.getUsername());
				trade.setMoney(bd.getMoney());
				//trade.setFundOptLevelCode(fundOptLevelCode);
				//trade.setPayPass(payPass);
				trade.setInOrOut(2);
				trade.setPayTime(date);
				trade.setTradeUserId(userId);
				trade.setTradeUsername(username);
				trade.setTradeUserPhone(userPhone);
				trade.setTradeStatusCode("trade_status_done");
				trade.setCreatedBy(username);
				json = cfService.outcomeFrozenMoneyToUserAvaliable(json, trade, username);
				if( Result.hasError(json) ){return json;}
				
				BonusDetail newDB = new BonusDetail();
				newDB.setId(bd.getId());
				newDB.setUserId(userId);
				newDB.setUsername(username);
				newDB.setName(username);
				newDB.setDealTime(date);
				newDB.setMainStatus(2);//已接收
				newDB.setUpdatedAt(date);
				newDB.setUpdatedBy(username);
				bdMappper.updateByPrimaryKeySelective(newDB);
				//更新chat
				BaseChat chat = chatList.get(0);
				BaseChat newChat = new BaseChat();
				newChat.setId(chat.getId());
				newChat.setReadTime(date);//已阅读
				newChat.setMainStatus(2);//已处理
				chatMapper.updateByPrimaryKeySelective(newChat);
				// _@微信消息通知WxNotice@_
				WxMessageFactory.receiveBonusSuccessForReceiver(user.getWxOpenid(), username, moneyStr);
				String timeStr = DateFormat.format(date, DateFormat.SECONDS_FORMAT2);
				WxMessageFactory.receiveBonusSuccessForSender(bossUser.getWxOpenid(), bossUser.getUsername(), moneyStr, timeStr);
				
				json.put("bonusId", bonusId);
				json.put("money", tradeMoney);//返回红包的金额
				success = true;
				break;//收到了一个红包就不再循环，避免收取了多个红包
			}else{
				Bonus newB = new Bonus();//更新bonus状态
				newB.setId(bonusId);
				newB.setMainStatus(2);//已全部接收
				newB.setUpdatedAt(date);
				newB.setUpdatedBy(username);
				bonusMappper.updateByPrimaryKeySelective(newB);
			}
		}
		if(!success){ 
			return Result.failure(json, "红包已经被抢光了", "bonusList_null"); 
		}
		return json;
	}
	
	public JSONObject receiveGroupBonus(Integer bossId, BaseUser user, JSONObject json){//, Integer bonusLinkType, Integer bonusLinkId
		Integer userId = user.getId();
		String username = user.getUsername();
		String userPhone = user.getPhone();
		Date date = new Date();
		Map<String,Object> map = new HashMap<String,Object>();
		map.clear();
		map.put("userId", bossId);
		//map.put("bonusLinkType", bonusLinkType);
		//map.put("bonusLinkId", bonusLinkId);
		map.put("notDeal", 1);
		List<Bonus> bonusList = bonusMappper.selectListByCondition(map);
		if( Check.isNull(bonusList)){ 
			return Result.failure(json, "红包已经被抢光了", "bonusList_null"); 
		}
		boolean haveAvaliable = false;
		boolean haveReceived = false;
		for(Bonus b : bonusList){
			haveReceived = false;
			Integer bonusId = b.getId();
			map.clear();
			map.put("bonusId", bonusId);
			map.put("dealt", 1);//dealt notDeal
			List<BonusDetail> dealtBDList = bdMappper.selectListByCondition(map);
			int intUserId = userId.intValue();
			for(BonusDetail bd : dealtBDList){
				Integer receiverId = bd.getUserId();
				if(null != receiverId && receiverId.intValue() == intUserId){
					haveReceived = true;
					break;//如果该用户已经收到过一条bonus的红包，就跳过，如果全部跳过，则没有可领取的红包
				}
			}
			if(haveReceived){
				continue;//这里不用break,每个bonusList可以领取一次,所有bonusList中，只有一个是没有领取过的则可以领取
			}
			//如果能执行到这里，说明有可以领取的红包
			map.clear();
			map.put("bonusId", bonusId);
			map.put("notDeal", 1);
			map.put("start", 0);
			map.put("count", 1);
			List<BonusDetail> bdList = bdMappper.selectListByCondition(map);
			if(null != bdList && bdList.size() > 0){
				BonusDetail bd = bdList.get(0);
				BigDecimal tradeMoney = bd.getMoney();
				if(null == tradeMoney || tradeMoney.doubleValue() <= 0){
					return Result.failure(json, "红包金额不正确", "bonusMoney_error"); 
				}
				//处理资金变更
				//TODO 修改
				//String linkUrl = "/bonusReceived";
				String moneyStr = String.valueOf(bd.getMoney());
				BaseUser bossUser = userMapper.selectByPrimaryKey(bossId);
				Trade trade = new Trade();
				trade.setUserId(bossUser.getId());
				trade.setPhone(bossUser.getPhone());
				trade.setUsername(bossUser.getUsername());
				trade.setMoney(bd.getMoney());
				//trade.setFundOptLevelCode(fundOptLevelCode);
				//trade.setPayPass(payPass);
				trade.setInOrOut(2);
				trade.setPayTime(date);
				trade.setTradeUserId(userId);
				trade.setTradeUsername(username);
				trade.setTradeUserPhone(userPhone);
				trade.setTradeStatusCode("trade_status_done");
				trade.setCreatedBy(username);
				json = cfService.outcomeFrozenMoneyToUserAvaliable(json, trade, username);
				if( Result.hasError(json) ){return json;}
				
				BonusDetail newDB = new BonusDetail();
				newDB.setId(bd.getId());
				newDB.setUserId(userId);
				newDB.setUsername(username);
				newDB.setName(username);
				newDB.setDealTime(date);
				newDB.setMainStatus(2);//已接收
				newDB.setUpdatedAt(date);
				newDB.setUpdatedBy(username);
				bdMappper.updateByPrimaryKeySelective(newDB);
				
				// _@微信消息通知WxNotice@_
				WxMessageFactory.receiveBonusSuccessForReceiver(user.getWxOpenid(), username, moneyStr);
				String timeStr = DateFormat.format(date, DateFormat.SECONDS_FORMAT2);
				WxMessageFactory.receiveBonusSuccessForSender(bossUser.getWxOpenid(), bossUser.getUsername(), moneyStr, timeStr);
				
				json.put("bonusId", bonusId);
				json.put("money", tradeMoney);//返回红包的金额
				haveAvaliable = true;
				break;//收到了一个红包就不再循环，避免收取了多个红包
			}else{
				Bonus newB = new Bonus();//更新bonus状态
				newB.setId(bonusId);
				newB.setMainStatus(2);//已全部接收
				newB.setUpdatedAt(date);
				newB.setUpdatedBy(username);
				bonusMappper.updateByPrimaryKeySelective(newB);
			}
		}
		if(haveReceived){ 
			return Result.failure(json, "您已经抢到红包了，不要再重复抢啦", "bonusList_null"); 
		}
		if(!haveAvaliable){ 
			return Result.failure(json, "红包已经被抢光了", "bonusList_null"); 
		}
		return json;
	}
	
	
	/*public static void main(String[] args) {  
    Scanner sc = new Scanner( System.in );  
    //System.out.println( "请输入总金额：" );  
    double totalMoney = sc.nextDouble();  
    //System.out.println( "请输入获取红包人数：" );  
    int personNum = sc.nextInt();  
    double[] allocationMoney = new double[personNum];   
    for ( int i = personNum; i > 1; i-- ) {  
        //double surplusMoney = totalMoney - ( i - 1 ) * 0.01;  
        //安全线  
        double surplusMoney = ( totalMoney - ( i - 1 ) * 0.01 ) / ( i / 2 );  
        //设surplusMoney为15，1、获取[0,1500)随机数，2、获取  
        //[1,1500]随机数，3、获取[0.01,15.00]随机数  
        double randomlyAssignedMoney = ( (int)( Math.random() * surplusMoney * 100 ) + 1 ) * 0.01;  
        //截取小数点后两位输出  
        BigDecimal aBigDecimal = new BigDecimal(  randomlyAssignedMoney );  
        double moneyOfOnePerson = aBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
        //System.out.println( moneyOfOnePerson );  
        totalMoney -= randomlyAssignedMoney;  
        allocationMoney[i-1] = randomlyAssignedMoney;   
    }  
    BigDecimal bg = new BigDecimal( totalMoney );  
    double remainingMoney = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
    //System.out.println( remainingMoney );  
    allocationMoney[0] = remainingMoney;  
    double checkTotalMoney = 0;   
    for( int i = 0; i < personNum; i++ ) {  
        checkTotalMoney += allocationMoney[i];  
    }  
    //System.out.println( checkTotalMoney );  
}  */
	
}
